package fun.diaoer.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import fun.diaoer.config.security.DiaoerAccessDeniedHandler;
import fun.diaoer.config.security.DiaoerAuthenctiationFailureHandler;
import fun.diaoer.config.security.DiaoerAuthenctiationSuccessHandler;
import fun.diaoer.config.security.DiaoerAuthenticationEntryPoint;
import fun.diaoer.config.security.DiaoerAuthenticationProvider;
import fun.diaoer.config.security.DiaoerLogoutSuccessHandler;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	
	/**
	 * 忽略安全校验
	 */
	private static final String[] IGNORE_RESOURCES = new String[] { "/","/js/**", "/css/**", "/font-awesome/**", "/fonts/**", "/images/**"};
	/*@Autowired
	private DiaoerUserDetailService diaoerUserDetailService;*/
	@Autowired
	private DiaoerAuthenctiationSuccessHandler successHandler;
	@Autowired
	private DiaoerAuthenctiationFailureHandler failureHandler;
	@Autowired
	private DiaoerAccessDeniedHandler accessDeniedHandler;
	@Autowired
	private DiaoerAuthenticationEntryPoint entryPoint;
	@Autowired
	private DiaoerLogoutSuccessHandler logoutSuccessHandler;
	@Autowired
	private DiaoerAuthenticationProvider diaoerProvider;
	/*@Autowired
	private AdminAuthenticationProvider adminProvider;*/
	
	
	/**
	 * 跨域请求配置
	 * @return
	 */
	private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }
	@Bean 
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
	
	@Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
    }
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable().httpBasic().authenticationEntryPoint(entryPoint)
		.and().formLogin()
		.successHandler(successHandler)
		.failureHandler(failureHandler)
		.and().logout().logoutSuccessHandler(logoutSuccessHandler)
		.and().authorizeRequests().antMatchers("/login","/diaoer/**","/auth/login","/auth/register","/auth/isLogin").permitAll().anyRequest().authenticated();
		http.rememberMe().rememberMeServices(rememberMeServices());
		//无权限handler
		http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
		
	}
	
	/**
	 * remember me 
	 * @return
	 */
	@Bean
	public SpringSessionRememberMeServices rememberMeServices() {
		SpringSessionRememberMeServices rememberMeServices = new SpringSessionRememberMeServices();
		// optionally customize
		rememberMeServices.setAlwaysRemember(true);
		return rememberMeServices;
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.authenticationProvider(diaoerProvider);
	}
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**").antMatchers(IGNORE_RESOURCES);
	}
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

}
